package mspbots.data.sync.rippling.receivers;

import com.fasterxml.jackson.databind.JsonNode;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import mspbots.data.sync.BaseReceiver;
import mspbots.data.sync.ResultMessageModel;
import mspbots.data.sync.rippling.model.RipplingCompanyActivity;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.time.Duration;
import java.util.Iterator;
import java.util.Optional;

/**
 * @author Jay Yang
 */
@Log4j2
@Component
@RequiredArgsConstructor
public class RipplingCompanyActivityReceiver extends BaseReceiver {

    @RabbitListener(queues = "rippling.company_activity.sync")
    public void processCompanyActivity(ResultMessageModel model) {
        log.debug("processCompanyActivity[rippling.company_activity.sync] ResultMessageModel {}", model);
        if (ResultMessageModel.MessageModelAction.ADD.equals(model.getAction())) {
            Iterator<JsonNode> eventsNode = model.getEntity().get("data").get("events").elements();
            while (eventsNode.hasNext()) {
                JsonNode activityNode = eventsNode.next();
                RipplingCompanyActivity activity = this.objectMapper.convertValue(activityNode, RipplingCompanyActivity.class);
                activity.setExtend(activityNode);
                activity.setTenantId(model.getTenantId());
                activity.setSyncTime(model.getSendTime());

                Optional<Long> id = this.databaseClient.execute("select id from rippling_company_activity " +
                        "where tenant_id =:tenantId and other_id =:otherId")
                        .as(Long.class)
                        .bind("tenantId", activity.getTenantId())
                        .bind("otherId", activity.getOtherId())
                        .fetch().one().blockOptional(Duration.ofSeconds(10));

                if (id.isPresent() && id.get() > 0) {
                    activity.setId(id.get());
                    this.databaseClient.update().table(RipplingCompanyActivity.class).using(activity).fetch().rowsUpdated().subscribe();
                } else {
                    this.databaseClient.insert().into(RipplingCompanyActivity.class).using(activity).fetch().rowsUpdated().subscribe();
                }
            }
        }
    }
}
